package com.efast.cafe.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.springframework.web.multipart.MultipartFile;

import com.efast.cafe.framework.exception.FileUtilException;

/**
 * 文件操作处理
 * 
 * @author swl
 * @version 2014-07-08
 * @since jdk1.6
 *
 */
public class FileUtil {

	/**
	 * 创建文件
	 * 
	 * @param myFile
	 * 
	 * @return boolean  返回是否创建成功信息
	 */
	public static boolean createFile(File myFile) throws FileUtilException {
		if (myFile == null) {
			throw new FileUtilException("请指定要创建的文件");
		}
		if (myFile.isDirectory()) {
			createDirectory(myFile);
			return true;
		}

		try {
			createDirectory(myFile);
			myFile.createNewFile();
			return true;
		} catch (IOException e) {
			throw new FileUtilException("文件创建失败", e);
		}

	}
	/**
	 * 删除文件
	 * 
	 * @param myFile
	 * 
	 * @return boolean  返回是否删除成功信息
	 */
	public static boolean deleteFile(File myFile) throws FileUtilException {
		if (myFile == null)
			throw new FileUtilException("你未指定你要删除的文件");
		if (myFile.isDirectory())
			throw new FileUtilException("你指定的是一个文件夹,不能删除");
		if (myFile.isFile()) {
			return myFile.delete();
		}
		throw new FileUtilException("你指定的文件不存在");
	}
	/**
	 * 获取文件列表
	 * 
	 * @param 
	 * 
	 * @return List  返回文件列表
	 */
	public static List getFileList(File myFile) {
		List l = new ArrayList();
		if (myFile.isDirectory()) {
			File[] f = myFile.listFiles();
			for (int k = 0; k < f.length; k++) {
				if (!f[k].isFile())
					continue;
				l.add(f[k]);
			}
		}

		return l;
	}
	/**
	 * 创建文件目录
	 * 
	 * @param 
	 * 
	 * @return List  返回创建文件目录成功与否信息
	 */
	public static boolean createDirectory(File myFile) {
		File tempFile = null;
		String tempFilePath = "";
		if (myFile.isFile())
			tempFile = myFile;
		else
			tempFile = myFile.getParentFile();
		
		String path = null;
		
		if ((tempFile.getAbsolutePath() == null) || ("".equals(tempFile.getAbsolutePath())) || ("null".equals(tempFile.getAbsolutePath()))
				|| ("NULL".equals(tempFile.getAbsolutePath()))) {
			path="";
		}else{
			path = tempFile.getAbsolutePath().replaceAll(">", "&gt;");
			path = path.replaceAll("<", "&lt;");
		}
		
		path = path.replace("\\", "/");
		
		String[] fileName = path.split( "/");
		for (int kk = 0; kk < fileName.length; kk++) {
			tempFilePath = tempFilePath + fileName[kk] + "/";
			if ((!tempFilePath.startsWith("/"))
					&& (tempFilePath.indexOf(":") != 1)) {
				tempFilePath = "/" + tempFilePath;
			}

			tempFile = new File(tempFilePath);
			tempFile.mkdir();
		}
		return true;
	}
	public static void main(String[] args) {
		System.out.println("c:/aa/b/c.txt".split("/").length);
		System.out.println("c:\\aa\\ba\\ac.txt".replace("a","d"));
		System.out.println(UUID.randomUUID().toString());
		System.out.println(UUID.randomUUID().toString());
		System.out.println(UUID.randomUUID().toString());
	}
	
	/**
	 * 删除文件目录
	 * 
	 * @param File dir
	 * 
	 * @return List  返回删除文件目录成功与否信息
	 * @throws FileUtilException 
	 */
	public static boolean deleteDirectory(File dir) throws FileUtilException {
		
		if ((dir == null) || (!dir.isDirectory())) {
			throw new FileUtilException("Argument " + dir
					+ " is not a directory. ");
		}
		File[] entries = dir.listFiles();
		int sz = entries.length;
		for (int i = 0; i < sz; i++) {
			if (entries[i].isDirectory()) {
				if (!deleteDirectory(entries[i])) {
					return false;
				}

			} else if (!entries[i].delete()) {
				return false;
			}

		}

		return dir.delete();
	}
	
	/**
	 * 更新文件
	 * 
	 * @param fileText  更新的文件内容
	 * 
	 * @return List  返回更新文件成功与否信息
	 */
	public static boolean updateFile(File myFile,String fileText) throws FileUtilException {
		myFile.delete();
		return writeFile(myFile,fileText);
	}
	/**
	 * 写入文件
	 * 
	 * @param myFile  被写入文件
	 * @param str  写入文件内容
	 * 
	 * @return List  返回写入文件成功与否信息
	 */
	public static boolean writeFile(File myFile,String str) throws FileUtilException {
		if (myFile == null) {
			throw new FileUtilException("请指定要与入的文件");
		}
		if (!myFile.isFile()) {
			throw new FileUtilException("对不起，你指定的不是文件");
		}
		try {
			BufferedWriter fout = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(myFile), "UTF-8"));
			PrintWriter out = new PrintWriter(fout);

			out.println(str);

			out.close();
		} catch (IOException e) {
			throw new FileUtilException("写入文件失败", e);
		}
		return true;
	}
	
	
	/**
	 * 写入文件
	 * 
	 * @param is  写入文件内容
	 * 
	 * @return List  返回写入文件成功与否信息
	 */
	public static boolean writeFile(File myFile,InputStream is) throws FileUtilException {
		String tempStr = "";
		if (myFile == null) {
			throw new FileUtilException("请指定要与入的文件");
		}
		if (!myFile.isFile()) {
			throw new FileUtilException("对不起，你指定的不是文件");
		}
		try {
			FileOutputStream out = new FileOutputStream(myFile);
			byte[] data = new byte[is.available()];
			is.read(data);
			out.write(data);
			is.close();
			out.close();
		} catch (IOException e) {
			throw new FileUtilException("写入文件失败", e);
		}
		return true;
	}
	/**
	 * 读取文件
	 * 
	 * @param myFile
	 * 
	 * @return String  返回读取文件信息
	 */
	public String readFile(File myFile) throws FileUtilException {
		String tempStr = "";
		String tempStr2 = "";
		if (myFile == null) {
			throw new FileUtilException("请指定要读取的文件");
		}
		if (!myFile.isFile()) {
			throw new FileUtilException("对不起，你读取的不是文件");
		}
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(
					new FileInputStream(myFile), "UTF-8"));

			while ((tempStr = in.readLine()) != null) {
				tempStr2 = tempStr2 + tempStr + "\n";
			}
			in.close();
		} catch (IOException e) {
			throw new FileUtilException("读取文件失败", e);
		}
		return tempStr2;
	}
	/**
	 * 读取文件
	 * 
	 * @param myFile
	 * 
	 * @return StringBuffer  返回读取文件内容
	 */
	public StringBuffer readFileBuffer(File myFile) throws FileUtilException {
		StringBuffer tempStr = new StringBuffer();
		String line = "";
		if (myFile == null) {
			throw new FileUtilException("请指定要读取的文件");
		}
		if (!myFile.isFile()) {
			throw new FileUtilException("对不起，你读取的不是文件");
		}
		try {
			BufferedReader in = new BufferedReader(new FileReader(myFile));
			while ((line = in.readLine()) != null) {
				tempStr.append(line + "\n");
			}
			in.close();
		} catch (IOException e) {
			throw new FileUtilException("写入文件失败", e);
		}
		return tempStr;
	}
	/**
	 * 读取文件
	 * 
	 * @param myFile
	 * 
	 * @return byte[]  返回读取文件内容
	 */
	public static byte[] readFileByte(File myFile) throws FileUtilException {
		String tempStr = "";
		String tempStr2 = "";
		if (myFile == null) {
			throw new FileUtilException("请指定要读取的文件");
		}
		if (!myFile.isFile()) {
			throw new FileUtilException("对不起，你读取的不是文件");
		}
		try {
			BufferedReader in = new BufferedReader(new FileReader(myFile));
			while ((tempStr = in.readLine()) != null) {
				tempStr2 = tempStr2 + tempStr;
			}
			in.close();
		} catch (IOException e) {
			throw new FileUtilException("写入文件失败", e);
		}
		return tempStr2.getBytes();
	}
	
	/**
	 * 创建目录以及必需的上级目录
	 * 
	 * @param pathName
	 * @throws IOException
	 */
	public static void createDir(String pathName) throws IOException {
		if (pathName == null) {
			return;
		}
		File file = new File(pathName);
		file.mkdirs();
	}
	
	/**
	 * Write byte array into file
	 * 
	 * @param bytes
	 *            byte array which will be written to file
	 * @param fileName
	 *            File name to store the byte array
	 * @param append
	 *            true,will append the file if it's exist;false,override. If
	 *            file is not exist,create a new one(Ignore isOverride).
	 */
	public static void writeFile(byte[] bytes, String fileName, boolean append)
			throws IOException {
		//
		File file = new File(fileName);
		createDir(file.getParent()); // 如果目录不存在,创建
		FileOutputStream fos = new FileOutputStream(file, append);
		ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
		//
		try {

			byte[] buf = new byte[1024];
			int bytesRead = 0;
			while (bytesRead >= 0) {
				fos.write(buf, 0, bytesRead);
				bytesRead = bis.read(buf);
			}

			// fos.write(bytes);
		} catch (IOException e) {
			throw e;
		} finally {
			try {
				bis.close();
				fos.flush();
				fos.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}
	
	/**
	 * Write byte array into file
	 * 
	 * @param bytes
	 *            byte array which will be written to file
	 * @param fileName
	 *            File name to store the byte array
	 */
	public static void writeFile(byte[] bytes, String fileName)
			throws IOException {
		writeFile(bytes, fileName, false);
	}
	
	/**
	 * 拷贝源文件到目标目录
	 * 
	 * @param myFile
	 * @param destPath
	 * @throws IOException
	 * @throws FileUtilException 
	 */
	public static void copyFile(File myFile, String destPath)
			throws IOException, FileUtilException {
		// 读取数据
		byte[] data = readFileByte(myFile);
		// 构造目标文件名
		//File file = new File(fileName);
		String destFile = destPath + "/" + myFile.getName();
		// 写数据
		writeFile(data, destFile);
	}

	/**
	 * 移动源文件到目标目录
	 * 
	 * @param myFile
	 * @param destPath
	 * @throws IOException
	 * @throws FileUtilException 
	 */
	public static void moveFile(File myFile, String destPath)
			throws IOException, FileUtilException {
		// 读取数据
		byte[] data = readFileByte(myFile);
		// 构造目标文件名
		//File file = new File(fileName);
		String destFile = destPath + "/" + myFile.getName();
		// 写数据
		writeFile(data, destFile);
		// 删除源文件
		myFile.delete();
	}
	
	/**
	 * 指定文件名，保存文件到指定目录
	 * 
	 * @param path
	 * @param fileName
	 * @param file
	 * @return String
	 * 
	 */
	public static String saveFile(String path, String fileName, File file) {
		String fileRealName = new StringBuffer(fileName.substring(0, fileName.lastIndexOf(".")))
								.append("-")
								.append(UUID.randomUUID().toString())
								.append(fileName.substring(fileName.lastIndexOf(".")))
								.toString();
        if(path != null && !path.equals("")){
			File fileDirectory = new File(path);
			if(!fileDirectory.exists()){
				fileDirectory.mkdirs();
			}
		}
        File targetFile = null;
        FileInputStream fistream = null;
        FileOutputStream fostream = null;
        try {
        	fistream = new FileInputStream(file);
            targetFile = new File(path + File.separator + fileRealName);
            fostream = new FileOutputStream(targetFile);
            byte[] buffer = new byte[1024];  
            int length = 0;  
            while ((length = fistream.read(buffer)) > 0) {  
            	fostream.write(buffer, 0, length);  
            }  
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fistream != null) {
                try {
                	fistream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fostream != null) {
                try {
                	fostream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
		return fileRealName;
	}
	
	
	/**
	 * 指定文件名，保存文件到指定目录
	 * 
	 * @param path
	 * @param fileName
	 * @param file
	 * @return String
	 * 
	 */
	public static String saveFile(String path, String fileName, MultipartFile file) {
		String fileRealName = new StringBuffer(fileName.substring(0, fileName.lastIndexOf(".")))
								.append("-")
								.append(UUID.randomUUID().toString())
								.append(fileName.substring(fileName.lastIndexOf(".")))
								.toString();
        if(path != null && !path.equals("")){
			File fileDirectory = new File(path);
			if(!fileDirectory.exists()){
				fileDirectory.mkdirs();
			}
		}
        File targetFile = null;
        InputStream fistream = null;
        FileOutputStream fostream = null;
        try {
        	fistream = file.getInputStream();
            targetFile = new File(path + File.separator + fileRealName);
            fostream = new FileOutputStream(targetFile);
            byte[] buffer = new byte[1024];  
            int length = 0;  
            while ((length = fistream.read(buffer)) > 0) {  
            	fostream.write(buffer, 0, length);  
            }  
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fistream != null) {
                try {
                	fistream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fostream != null) {
                try {
                	fostream.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
		return fileRealName;
	}
	


	/**
	 * 去掉文件名中不合法的字符并返回修改后的文件名 不合法的字符被替换成空格
	 * 
	 * @param fileName
	 * @return
	 */
	public static String clearFileName(String fileName) {
		if (fileName == null || fileName.length() == 0) {
			return fileName;
		}
		//
		char[] chrs = new char[fileName.length()];
		char chr;
		for (int i = 0; i < chrs.length; i++) {
			chr = fileName.charAt(i);
			// These characters is invalid in file name:\/:*?"<>|
			if (chr == '\\' || chr == '/' || chr == ':' || chr == '*'
					|| chr == '?' || chr == '"' || chr == '<' || chr == '>'
					|| chr == '|' || chr == '(' || chr == ')') {
				chr = ' ';
			}
			chrs[i] = chr;
		}
		//
		return new String(chrs);
	}
	
	public static byte[] File2byte(File file)
    {
        byte[] buffer = null;
        try
        {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return buffer;
    }

    public static void byte2File(byte[] buf, String filePath, String fileName)
    {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try
        {
            File dir = new File(filePath);
            if (!dir.exists() && dir.isDirectory())
            {
                dir.mkdirs();
            }
            file = new File(filePath + File.separator + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(buf);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (bos != null)
            {
                try
                {
                    bos.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            if (fos != null)
            {
                try
                {
                    fos.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

}